package com.chenxbook.modules.jbpm4.handler;

import org.apache.commons.collections4.CollectionUtils;
import org.jbpm.api.TaskService;
import org.jbpm.api.model.OpenExecution;
import org.jbpm.api.task.Assignable;
import org.jbpm.api.task.AssignmentHandler;
import org.jbpm.api.task.Participation;
import org.jbpm.api.task.Task;
import org.jbpm.pvm.internal.env.EnvironmentImpl;
import org.jbpm.pvm.internal.task.OpenTask;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * 专门用户会签活动的任务分配处理器实现
 * <br> 此处理器会根据participants成员域的定义的"会签参与者"动态创建出相应的子任务
 */
@Component
public class JointlySignAssignment implements AssignmentHandler {

    private static final long serialVersionUID = 3479263474773078028L;


    //会签参与者ID列表---在流程定义（jPDL）中注入
    private List<String> participants;

    private TaskService taskService;

    @Override
    public void assign(Assignable assignable, OpenExecution execution) throws Exception {
        String pid = execution.getProcessInstance().getId();
        //获取会签活动的主任务对象，基于此主任务为所有会签参与者创建子任务
        taskService = (TaskService)EnvironmentImpl.getFromCurrent("taskService");
        Task task = taskService.createTaskQuery().processInstanceId(pid).activityName(execution.getName()).uniqueResult();
        //创建会签子任务
        createSubTasks(task);
    }

    /**
     * 创建会签子任务
     * <br> 可行实现方案：既可以建立和主任务（及流程实例）关联，又可以随主任务一同持久化而避免异常。
     *
     * @param task 主任务
     **/
    private void createSubTasks(Task task) {
        if (CollectionUtils.isNotEmpty(participants)) {
            for (String participant : participants) {
                //使用主任务对象的方法createSubTask(不会触发持久化操作)为该会签参与者创建子任务
                Task subTask = ((OpenTask) task).createSubTask();
                //设置该会签者为子任务的分配者
                subTask.setAssignee(participant);
                //关联会签用户到主任务
                //Participation.CLIENT表示此用户是主任务的使用者之一，虽然不可以直接操作主任务，但可以对主任务添加注释，
                //可以用做将会签意见保存为主任务注释的目的。
                taskService.addTaskParticipatingUser(task.getId(), participant, Participation.CLIENT);
            }


        }

    }
}
